package com.iflytek.jzcpx.procuracy.card.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.iflytek.jzcpx.procuracy.card.common.enums.CardFileStatusEnum;
import com.iflytek.jzcpx.procuracy.card.dao.CardFileDao;
import com.iflytek.jzcpx.procuracy.card.entity.CardFile;
import com.iflytek.jzcpx.procuracy.card.service.CardFileService;
import com.iflytek.jzcpx.procuracy.ocr.common.constant.Constants;
import com.iflytek.sxs.dfs.client.FdfsClient;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

/**
 * @author <a href=mailto:ktyi@iflytek.com>伊开堂</a>
 * @date 2019-08-27 10:17
 */
@Service
public class CardFileServiceImpl extends ServiceImpl<CardFileDao, CardFile> implements CardFileService {
    private static final Logger logger = LoggerFactory.getLogger(CardFileServiceImpl.class);

    @Autowired
    private FdfsClient fdfsClient;

    @Override
    public boolean abnormalEnd(Long id, String errorInfo) {
        CardFile entity = new CardFile();
        entity.setId(id);
        entity.setStatus(CardFileStatusEnum.END.name());
        entity.setFailInfo(errorInfo);
        entity.setUpdateTime(new Date());

        boolean updateSuccess = updateById(entity);
        logger.info("更新案卡任务状态为异常结束{}, id[ {} ]", updateSuccess ? "成功" : "失败", id);

        return updateSuccess;
    }

    @Override
    public boolean updateByStoreOcrResult(Long id, String ocrStorePath) {
        CardFile entity = new CardFile();
        entity.setId(id);
        entity.setStatus(CardFileStatusEnum.OCR_ENGINE_RESULT_STORED.name());
        entity.setOcrResultPath(ocrStorePath);
        entity.setUpdateTime(new Date());

        boolean updateSuccess = updateById(entity);
        logger.info("更新案卡任务状态为 ocr 结果上传{}, id[ {} ]", updateSuccess ? "成功" : "失败", id);

        return updateSuccess;
    }

    @Override
    public boolean updateStatus(Long id, CardFileStatusEnum fileStatusEnum) {
        CardFile entity = new CardFile();
        entity.setId(id);
        entity.setStatus(fileStatusEnum.name());
        entity.setUpdateTime(new Date());

        boolean updateSuccess = updateById(entity);
        logger.info("更新案卡任务状态为{}{}, id[ {} ]", fileStatusEnum, updateSuccess ? "成功" : "失败", id);

        return updateSuccess;
    }

    @Override
    public boolean updateByStoreElleResult(Long id, String elleStorePath) {
        CardFile entity = new CardFile();
        entity.setId(id);
        entity.setStatus(CardFileStatusEnum.ELLE_ENGINE_RESULT_STORED.name());
        entity.setElleResultPath(elleStorePath);
        entity.setUpdateTime(new Date());

        boolean updateSuccess = updateById(entity);
        logger.info("更新案卡任务状态为 elle 结果上传{}, id[ {} ]", updateSuccess ? "成功" : "失败", id);

        return updateSuccess;
    }

    @Override
    public List<CardFile> findInHandleFiles(String bmsah) {
        if (StringUtils.isBlank(bmsah)) {
            return new ArrayList<>();
        }

        QueryWrapper<CardFile> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(CardFile::getBmsah, bmsah);
        return list(wrapper);
    }

    @Override
    public List<CardFile> findByWsslbh(String bmsah, String wsslbh) {
        if (StringUtils.isAnyBlank(bmsah, wsslbh)) {
            return null;
        }
        QueryWrapper<CardFile> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(CardFile::getBmsah, bmsah).eq(CardFile::getWsslbh, wsslbh);
        return list(wrapper);
    }

    @Override
    public List<CardFile> findByJzwjh(String bmsah, String jzwjh) {
        if (StringUtils.isAnyBlank(bmsah, jzwjh)) {
            return null;
        }
        QueryWrapper<CardFile> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(CardFile::getBmsah, bmsah).eq(CardFile::getJzwjh, jzwjh);
        return list(wrapper);
    }

    @Override
    public List<CardFile> listByBmsah(String bmsah) {
        if (StringUtils.isBlank(bmsah)) {
            return null;
        }
        QueryWrapper<CardFile> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(CardFile::getBmsah, bmsah);
        return list(wrapper);
    }

    @Override
    public boolean updateStatusAndFileContent(Long cardFileId, CardFileStatusEnum fileStatusEnum, String fileContent) {
        CardFile entity = new CardFile();
        entity.setId(cardFileId);
        entity.setStatus(fileStatusEnum.name());
        entity.setFileContent(fileContent);
        entity.setUpdateTime(new Date());

        boolean updateSuccess = updateById(entity);
        logger.info("更新案卡任务状态为{}{}, id[ {} ]", fileStatusEnum, updateSuccess ? "成功" : "失败", cardFileId);

        return updateSuccess;
    }

	@Override
	public boolean updateBmsahByWjbm(String wjbm, String bmsah) {
		CardFile entity = new CardFile();
		entity.setBmsah(bmsah);
		entity.setUpdateTime(new Date());
		
		UpdateWrapper<CardFile> updateWrapper=new UpdateWrapper<>();
		updateWrapper.lambda().eq(CardFile::getWjbm, wjbm);
		boolean updateSuccess=this.update(entity, updateWrapper);
		logger.info("更新部门受案号   bmsah{} wjbm{} ", bmsah,wjbm,updateSuccess ? "成功" : "失败");
		return updateSuccess;
	}

    @Override
    public int cleanData(Date startDatetime, Date endDatetime, boolean cleanDB, boolean cleanFdfs) {
        if (!cleanDB && !cleanFdfs) {
            logger.warn("即不清理DB, 又不清理fastDFS, 你清理个毛啊");
            return 0;
        }

        logger.info("清理cardFile数据, 起止时间: {} - {}", startDatetime, endDatetime);
        Assert.isTrue(startDatetime != null || endDatetime != null, "开始和结束时间不能同时为空");

        int cleanCount = 0;

        List<CardFile> cardFiles = null;
        int pageSize = 100;
        int pageNum = 1;
        do {
            Page<CardFile> page = new Page<>(pageNum, pageSize);
            LambdaQueryWrapper<CardFile> wrapper = new LambdaQueryWrapper<>();
            if (startDatetime != null) {
                wrapper.gt(CardFile::getCreateTime, startDatetime);
            }
            if (endDatetime != null) {
                wrapper.lt(CardFile::getCreateTime, endDatetime);
            }
            IPage<CardFile> cardFilePage = this.baseMapper.selectPage(page, wrapper);
            if (cardFilePage == null || CollectionUtils.isEmpty(cardFilePage.getRecords())) {
                logger.info("没有待清理的cardFile数据了");
                return cleanCount;
            }

            cardFiles = cardFilePage.getRecords();
            logger.debug("查询到待清理的cardFile数据, size: {}, page: {}", cardFiles.size(), page);

            for (CardFile cardFile : cardFiles) {
                if (deleteDataAndFile(cardFile, cleanDB, cleanFdfs)) {
                    cleanCount++;
                }
            }

            if (!cleanDB) {
                pageNum++;
            }
        } while (CollectionUtils.size(cardFiles) >= pageSize);

        return cleanCount;
    }

    private boolean deleteDataAndFile(CardFile cardFile, boolean cleanDB, boolean cleanFdfs) {
        logger.info("删除cardFile数据, cardFile: {}", cardFile);
        if (cleanDB) {
            logger.info("删除cardFile数据库数据, cardFileId: {}", cardFile.getId());
            removeById(cardFile);
        }
        if (cleanFdfs) {
            String ocrResultPath = cardFile.getOcrResultPath();
            String elleResultPath = cardFile.getElleResultPath();
            if (StringUtils.isNotBlank(ocrResultPath)) {
                String[] pathArray = ocrResultPath.split(Constants.CARDFILE_OCRPATH_SEPERATOR);
                for (String path : pathArray) {
                    logger.info("删除fastDFS文件, cardFileId: {}, path: {}", cardFile.getId(), path);
                    try {
                        fdfsClient.deleteFile(path);
                    }
                    catch (Exception e) {
                        logger.warn("删除fastDFS文件异常, cardFileId: {}, path: {}, errorInfo: {}", cardFile.getId(), path,
                                    e.getMessage());
                    }
                }
            }

            if (StringUtils.isNotBlank(elleResultPath)) {
                logger.info("删除fastDFS文件, cardFileId: {}, elleResultPath: {}", cardFile.getId(), elleResultPath);
                try {
                    fdfsClient.deleteFile(elleResultPath);
                }
                catch (Exception e) {
                    logger.warn("删除fastDFS文件异常, cardFileId: {}, elleResultPath: {}, errorInfo: {}", cardFile.getId(),
                                elleResultPath, e.getMessage());
                }
            }

        }
        return true;
    }
}
